package divert

import "fmt"

type Protocol uint8

const (
	IPPROTO_HOPOPTS Protocol = 0 // IPv6 Hop-by-Hop options

	IPPROTO_ICMP Protocol = 1
	IPPROTO_IGMP Protocol = 2
	IPPROTO_GGP  Protocol = 3

	IPPROTO_IPV4 Protocol = 4
	IPPROTO_ST   Protocol = 5
	IPPROTO_TCP  Protocol = 6

	IPPROTO_CBT Protocol = 7
	IPPROTO_EGP Protocol = 8
	IPPROTO_IGP Protocol = 9

	IPPROTO_PUP Protocol = 12
	IPPROTO_UDP Protocol = 17
	IPPROTO_IDP Protocol = 22

	IPPROTO_RDP Protocol = 27

	IPPROTO_IPV6     Protocol = 41
	IPPROTO_ROUTING  Protocol = 43
	IPPROTO_FRAGMENT Protocol = 44
	IPPROTO_ESP      Protocol = 50
	IPPROTO_AH       Protocol = 51
	IPPROTO_ICMPV6   Protocol = 58
	IPPROTO_NONE     Protocol = 59
	IPPROTO_DSTOPTS  Protocol = 60

	IPPROTO_ND Protocol = 77

	IPPROTO_ICLFXBM Protocol = 78

	IPPROTO_PIM  Protocol = 103
	IPPROTO_PGM  Protocol = 113
	IPPROTO_L2TP Protocol = 115
	IPPROTO_SCTP Protocol = 132

	IPPROTO_RAW Protocol = 255
)

func (c Protocol) String() string {
	switch c {
	case IPPROTO_TCP:
		return "TCP"
	case IPPROTO_UDP:
		return "UDP"
	case IPPROTO_ICMP:
		return "ICMP"
	case IPPROTO_IPV4:
		return "IPV4"
	case IPPROTO_IPV6:
		return "IPV6"
	case IPPROTO_ESP:
		return "ESP"
	case IPPROTO_AH:
		return "AH"
	default:
		return fmt.Sprintf("%v", uint8(c))
	}
}

type WINDIVERT_LAYER int32

const (
	WINDIVERT_LAYER_NETWORK         WINDIVERT_LAYER = 0 /* Network layer. */                    // Network packets to/from the local machine. This is the default layer.
	WINDIVERT_LAYER_NETWORK_FORWARD WINDIVERT_LAYER = 1 /* Network layer (forwarded packets) */ // Network packets passing through the local machine.
	WINDIVERT_LAYER_FLOW            WINDIVERT_LAYER = 2 /* Flow layer. */                       // Network flow established/deleted events.
	WINDIVERT_LAYER_SOCKET          WINDIVERT_LAYER = 3 /* Socket layer. */                     // Socket operation events.
	WINDIVERT_LAYER_REFLECT         WINDIVERT_LAYER = 4 /* Reflect layer. */                    // WinDivert handle events.
)

type WINDIVERT_PRIORITY int16

const (
	WINDIVERT_PRIORITY_HIGHEST = 30000
	WINDIVERT_PRIORITY_NORMAL  = 0
	WINDIVERT_PRIORITY_LOWEST  = -WINDIVERT_PRIORITY_HIGHEST
)

// WINDIVERT_FLAGS WinDivert flags.
type WINDIVERT_FLAGS uint64

const (
	WINDIVERT_FLAG_SNIFF      WINDIVERT_FLAGS = 0x0001 // This flag opens the WinDivert handle in packet sniffing mode. In packet sniffing mode the original packet is not dropped-and-diverted (the default) but copied-and-diverted. This mode is useful for implementing packet sniffing tools similar to those applications that currently use Winpcap. 此标志在数据包嗅探模式下打开WinDivert句柄。在数据包嗅探模式中，原始数据包不会被丢弃和转移（默认情况下），而是被复制和转移。此模式对于实现类似于当前使用Winpcap的应用程序的数据包嗅探工具非常有用。
	WINDIVERT_FLAG_DROP       WINDIVERT_FLAGS = 0x0002 // This flag indicates that the user application does not intend to read matching packets with WinDivertRecv(), instead the packets should be silently dropped. This is useful for implementing simple packet filters using the WinDivert filter language. 此标志表示用户应用程序不打算使用WinDivertRecv（）读取匹配的数据包，而是应该静默地丢弃这些数据包。这对于使用WinDivert筛选器语言实现简单的数据包筛选器非常有用。
	WINDIVERT_FLAG_RECV_ONLY  WINDIVERT_FLAGS = 0x0004 // This flags forces the handle into receive only mode which effectively disables WinDivertSend(). This means that it is possible to block/capture packets or events but not inject them. 此标志强制句柄进入仅接收模式，从而有效地禁用WinDivertSend（）。这意味着可以阻止/捕获数据包或事件，但不能注入它们。
	WINDIVERT_FLAG_SEND_ONLY  WINDIVERT_FLAGS = 0x0008 // This flags forces the handle into send only mode which effectively disables WinDivertRecv(). This means that it is possible to inject packets or events, but not block/capture them. 此标志强制句柄进入仅发送模式，从而有效地禁用WinDivertRecv（）。这意味着可以注入数据包或事件，但不能阻止/捕获它们。
	WINDIVERT_FLAG_NO_INSTALL WINDIVERT_FLAGS = 0x0010 // This flags causes WinDivertOpen() to fail with ERROR_SERVICE_DOES_NOT_EXIST if the WinDivert driver is not already installed. This flag is useful for querying the WinDivert state using a WINDIVERT_LAYER_REFLECT handle. 如果尚未安装WinDivert驱动程序，则此标志会导致WinDiverOpen（）失败，并显示ERROR_SERVICE_DOES_NOT_EXIST。此标志用于使用WinDivert_LAYER_REFLECT句柄查询WinDivert状态。
	WINDIVERT_FLAG_FRAGMENTS  WINDIVERT_FLAGS = 0x0020 // If set, the handle will capture inbound IP fragments, but not inbound reassembled IP packets. Otherwise, if not set (the default), the handle will capture inbound reassembled IP packets, but not inbound IP fragments. This flag only affects inbound packets at the WINDIVERT_LAYER_NETWORK layer, else the flag is ignored. 如果设置，句柄将捕获入站IP片段，但不会捕获入站重新组装的IP数据包。否则，如果未设置（默认设置），句柄将捕获入站重新组装的IP数据包，但不会捕获入站IP片段。此标志仅影响WINDIVERT_LAYER_NETWORK层的入站数据包，否则将忽略该标志。
)

const (
	WINDIVERT_MTU_MAX = (40 + 0xFFFF)
)
